package com.echo.yixiaowu.service

import android.app.PendingIntent
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import androidx.annotation.OptIn
import androidx.compose.ui.platform.LocalContext
import androidx.media3.common.AudioAttributes
import androidx.media3.common.C
import androidx.media3.common.MediaItem
import androidx.media3.common.Player
import androidx.media3.common.util.Log
import androidx.media3.common.util.UnstableApi
import androidx.media3.exoplayer.DefaultLoadControl
import androidx.media3.exoplayer.DefaultRenderersFactory
import androidx.media3.exoplayer.ExoPlayer
import androidx.media3.exoplayer.audio.AudioCapabilities
import androidx.media3.exoplayer.trackselection.DefaultTrackSelector
import androidx.media3.exoplayer.upstream.DefaultAllocator
import androidx.media3.session.MediaSession
import androidx.media3.session.MediaSessionService
import com.echo.yixiaowu.main.MainActivity

@UnstableApi
class PlaybackService : MediaSessionService(), Player.Listener {
    private var mediaSession: MediaSession? = null
    private lateinit var player: ExoPlayer

    // 检查当前设备是否支持高保真度的32位浮点音频输出，以提升音质。
//    private val _isSupportsFloat =
//        AudioCapabilities.getCapabilities(this, AudioAttributes.DEFAULT, null)
//            .supportsEncoding(C.ENCODING_PCM_FLOAT)

    // 配置渲染器工厂，负责创建处理视频、音频、字幕等模块。
    private val _renderersFactory = DefaultRenderersFactory(this)
        // 启用解码器回退：当首选解码器（如硬件解码器）失败时，自动尝试使用备用解码器（如软件解码器），防止播放失败。
        .setEnableDecoderFallback(true)
        // 根据上面 _isSupportsFloat 的检查结果，在设备支持时启用高保真度的浮点音频输出以优化音质。
//        .setEnableAudioFloatOutput(_isSupportsFloat)
        // 设置扩展渲染器模式为“开启”，优先使用项目中添加的扩展库（如AV1, FLAC, Opus）来解码，以支持更多媒体格式。
        .setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_ON)

    // 配置轨道选择器
//    private val _defaultTrackSelector = DefaultTrackSelector(this).apply {
//        parameters = buildUponParameters()
//            // 不强制使用设备支持的最高码率轨道。
//            // 设置为 false 允许播放器进行自适应码率选择（ABR），
//            // 即根据当前网速动态切换到最合适的视频清晰度，以获得更流畅的播放体验。
//            .setForceHighestSupportedBitrate(false)
//            .build()
//    }

    // 配置“加载控制器”，定义播放器的缓冲策略
    private val _defaultLocalControl = DefaultLoadControl.Builder()
        // 设置缓冲时长（单位：毫秒）：
        // - minBufferMs: 播放开始前最少缓冲 5 秒。
        // - maxBufferMs: 播放时最多缓冲 120 秒（2分钟）的内容，防止占用过多资源。
        // - bufferForPlaybackMs: 播放中至少要维持 1 秒的缓冲才能继续播放。
        // - bufferForPlaybackAfterRebufferMs: 如果发生卡顿，需要重新缓冲到 5 秒才恢复播放。
        .setBufferDurationsMs(5_000, 120_000, 1_000, 5_000)
        // 配置内存分配器：使用640KB（默认64KB*10）为单位的内存块，并在播放器重置时释放内存。
        .setAllocator(DefaultAllocator(true, C.DEFAULT_BUFFER_SEGMENT_SIZE * 10))
        // 不优先考虑时间阈值：在做缓冲决策时，会同时考虑已缓冲时长和已用内存大小，使策略更灵活。
        .setPrioritizeTimeOverSizeThresholds(false)
        .build()

    override fun onCreate() {
        super.onCreate()
        player = ExoPlayer.Builder(this)
            .setRenderersFactory(_renderersFactory)
//            .setTrackSelector(_defaultTrackSelector)
            .setLoadControl(_defaultLocalControl)
            .build().apply {
                playWhenReady = false
                repeatMode = Player.REPEAT_MODE_OFF
            }
        player.addListener(this)
        mediaSession = MediaSession.Builder(this, player).build()
    }

    override fun onGetSession(controllerInfo: MediaSession.ControllerInfo): MediaSession? {
        return mediaSession
    }

    // 在 setMediaItem 时会进来调用
    override fun onMediaItemTransition(mediaItem: MediaItem?, reason: Int) {
        super.onMediaItemTransition(mediaItem, reason)
        updateSessionActivity()
    }

    @OptIn(UnstableApi::class)
    private fun updateSessionActivity() {
        val item = player.mediaMetadata.extras
        Log.i("PlaybackService", "updateSessionActivity")
        if (item is Bundle) {
            val itemId = item.getString("itemId")
            val itemType = item.getString("itemType")

            val deepLinkUri = Uri.parse("yixiaowu://main/detail/$itemType/$itemId")

            val playerActivityIntent = Intent(this, MainActivity::class.java).apply {
                data = deepLinkUri
            }

            val sessionActivityPendingIntent = PendingIntent.getActivity(
                this,
                0,
                playerActivityIntent,
                PendingIntent.FLAG_IMMUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
            )
            mediaSession?.setSessionActivity(sessionActivityPendingIntent)
        } else {
            Log.e("PlaybackService", "Tag is error")
        }
    }

    override fun onDestroy() {
        mediaSession?.run {
            player.release()
            release()
            mediaSession = null
        }
        super.onDestroy()
    }
}